{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3.5. 图像分类数据集（Fashion-MNIST）\n",
    "\n",
    "在介绍softmax回归的实现前我们先引入一个多类图像分类数据集。它将在后面的章节中被多次使用，以方便我们观察比较算法之间在模型精度和计算效率上的区别。图像分类数据集中最常用的是手写数字识别数据集MNIST [1]。但大部分模型在MNIST上的分类精度都超过了95%。为了更直观地观察算法之间的差异，我们将使用一个图像内容更加复杂的数据集Fashion-MNIST [2]。\n",
    "\n",
    "## 3.5.1. 获取数据集\n",
    "\n",
    "首先导入本节需要的包或模块。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow import keras\n",
    "import numpy as np\n",
    "import time\n",
    "import sys \n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面，我们通过keras的dataset包来下载这个数据集。第一次调用时会自动从网上获取数据。我们通过参数train来指定获取训练数据集或测试数据集（testing data set）。测试数据集也叫测试集（testing set），只用来评价模型的表现，并不用来训练模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz\n",
      "32768/29515 [=================================] - 0s 13us/step\n",
      "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz\n",
      "26427392/26421880 [==============================] - 7513s 284us/step\n",
      "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz\n",
      "8192/5148 [===============================================] - 1s 96us/step\n",
      "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz\n",
      "4423680/4422102 [==============================] - 54s 12us/step\n"
     ]
    }
   ],
   "source": [
    "from tensorflow.keras.datasets import fashion_mnist\n",
    "\n",
    "(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "训练集中和测试集中的每个类别的图像数分别为6,000和1,000。因为有10个类别，所以训练集和测试集的样本数分别为60,000和10,000。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(60000, 10000)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(x_train), len(x_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们可以通过方括号[]来访问任意一个样本，下面获取第一个样本的图像和标签。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "feature, label = x_train[0], y_train[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "变量feature对应高和宽均为28像素的图像。每个像素的数值为0到255之间8位无符号整数（uint8）。它使用二维的`numpy.ndarray`存储。因为数据集中是灰度图像，所以只有两个维度，不需要第三个维度来区分通道。为了表述简洁，我们将高和宽分别为 h 和 w 像素的图像的形状记为 h×w 或（h，w）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((28, 28), dtype('uint8'), numpy.ndarray)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "feature.shape, feature.dtype, type(feature)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "图像的标签使用NumPy的标量表示。注意，在keras的fashion_mnist数据和原书mxnet提供的数据集有差别"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(9, numpy.uint8, dtype('uint8'))"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "label, type(label), label.dtype"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Fashion-MNIST中一共包括了10个类别，分别为t-shirt（T恤）、trouser（裤子）、pullover（套衫）、dress（连衣裙）、coat（外套）、sandal（凉鞋）、shirt（衬衫）、sneaker（运动鞋）、bag（包）和ankle boot（短靴）。以下函数可以将数值标签转成相应的文本标签。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_fashion_mnist_labels(labels):\n",
    "    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',\n",
    "                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']\n",
    "    return [text_labels[int(i)] for i in labels]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面定义一个可以在一行里画出多张图像和对应标签的函数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def show_fashion_mnist(images, labels):\n",
    "    _, figs = plt.subplots(1, len(images), figsize=(12, 12))\n",
    "    for f, img, lbl in zip(figs, images, labels):\n",
    "        f.imshow(img.reshape((28, 28)))\n",
    "        f.set_title(lbl)\n",
    "        \n",
    "        f.axes.get_xaxis().set_visible(False)\n",
    "        f.axes.get_yaxis().set_visible(False)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "现在，我们看一下训练数据集中前9个样本的图像内容和文本标签"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x864 with 10 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "X, y = [], []\n",
    "for i in range(10):\n",
    "    X.append(x_train[i])\n",
    "    y.append(y_train[i])\n",
    "show_fashion_mnist(X, get_fashion_mnist_labels(y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.5.2. 读取小批量\n",
    "\n",
    "我们将在训练数据集上训练模型，并将训练好的模型在测试数据集上评价模型的表现。虽然我们可以像“线性回归的从零开始实现”一节中那样通过`yield`来定义读取小批量数据样本的函数，但为了代码简洁，这里我们直接创建`tf.data.Dataset.from_tensor_slices()`实例。该实例每次读取一个样本数`batch_size`的小批量数据。这里的批量大小`batch_size`是一个超参数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "bath_size = 256\n",
    "if sys.platform.startswith('win'):\n",
    "    num_workers = 0  # 0表示不用额外的进程来加速读取数据\n",
    "else:\n",
    "    num_workers = 4\n",
    "    \n",
    "train_iter = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(bath_size)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后我们查看读取一遍训练数据需要的时间。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.57 sec\n"
     ]
    }
   ],
   "source": [
    "start = time.time()\n",
    "for X, y in train_iter:\n",
    "    continue\n",
    "print('%.2f sec' % (time.time() - start))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.5.3. 小结\n",
    "\n",
    "- Fashion-MNIST是一个10类服饰分类数据集，之后章节里将使用它来检验不同算法的表现。\n",
    "- 我们将高和宽分别为 h 和 w 像素的图像的形状记为 h×w 或（h，w）。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
